﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Windows.Forms;
using Badge_Manager.Model;

namespace Badge_Manager.Controller
{
    public class ctrlPersona
    {
        private Persona persona;
        private ctrlTessera ctrlTessera = new ctrlTessera();
        private Connector connector = Connector.Istance();

        public List<Persona> SelectObjectPersona()
        {
            DataTable data = new DataTable();

            Connector con = Connector.Istance();
            SqlConnection conn = con.Connessione;

            string query = @"
            SELECT     Persone.id AS IdPersona, Persone.cognome AS CognomePersona, Persone.nome AS NomePersona, Persone.note AS NotePersona,Persone.idtessera AS IdTessera, Alunni.id AS IdAlunno, Dipendenti.id AS IdDipendente, Docenti.id AS IdDocente
            FROM       Persone LEFT OUTER JOIN
                       Alunni ON Persone.id = Alunni.id LEFT OUTER JOIN
                       Dipendenti ON Persone.id = Dipendenti.id LEFT OUTER JOIN
                       Docenti ON Persone.id = Docenti.id";
            SqlDataAdapter adapter = new SqlDataAdapter(query, conn);
            adapter.Fill(data);

            List<Persona> listaPersone = new List<Persona>();

            foreach (DataRow riga in data.Rows)
            {
                Persona persona = null;
                if (riga[0].Equals(riga[5])) //alunno
                {
                    persona = new Alunno();
                }
                if (riga[0].Equals(riga[6])) //dipendente
                {
                    persona = new Dipendente();
                }
                if (riga[0].Equals(riga[7])) //docente
                {
                    persona = new Docente();
                }

                persona.Id = (Guid)riga["IdPersona"];
                persona.Cognome = (string)riga["CognomePersona"];
                persona.Nome = (string)riga["NomePersona"];
                persona.Note = (string)riga["NotePersona"];
                ctrlTessera ctrlTessera = new Controller.ctrlTessera();
                if (riga["IdTessera"] != DBNull.Value)
                    persona.Tessera = ctrlTessera.GetTesseraById((Guid)riga["IdTessera"]);
                else
                    persona.Tessera = null;
                listaPersone.Add(persona);
            }
            return listaPersone;
        }

        public DataTable SelectAlunniCorsoAttivitàAttuale(Guid idAttività)
        {
            Controller.Connector conn = Controller.Connector.Istance();
            DataTable dataTable = new DataTable();
            string query = "SELECT Persone.id AS Id, Persone.nome AS Nome, Persone.cognome AS Cognome"
                            + " FROM Persone INNER JOIN Attivita ON Persone.idattivita = Attivita.id"
                            + " WHERE Attivita.id = '" + idAttività + "'";
            SqlDataAdapter sda = new SqlDataAdapter(query, conn.Connessione);
            sda.Fill(dataTable);
            return dataTable;
        }

        public DataTable SelectAllAlunniNonImpegnati()
        {
            DataTable data = new DataTable();

            Controller.Connector conn = Controller.Connector.Istance();
            SqlConnection provaConnessione = conn.Connessione;

            SqlDataAdapter com = new SqlDataAdapter("SELECT Persone.id AS Id, Persone.nome AS Nome, Persone.cognome AS Cognome "
                        + " FROM Persone LEFT JOIN "
                        + " Alunni ON Persone.id = Alunni.id "
                        + " WHERE Persone.idattivita IS NULL ", provaConnessione);
            com.Fill(data);

            return data;
        }

        public DataTable SelectAllAlunniCorsoFinito()
        {
            DataTable data = new DataTable();

            Controller.Connector conn = Controller.Connector.Istance();
            SqlConnection provaConnessione = conn.Connessione;

            SqlDataAdapter com = new SqlDataAdapter("SELECT Persone.id AS Id,Persone.nome AS Nome, Persone.cognome AS Cognome, MAX(DettaglioAttivita.giorno) AS MaxGiorno, Persone.idattivita, Persone.id, Persone.idtessera, Persone.note "
                    + " FROM DettaglioAttivita INNER JOIN "
                    + " Attivita ON DettaglioAttivita.idattivita = Attivita.id RIGHT OUTER JOIN "
                    + " Persone ON Attivita.id = Persone.idattivita "
                    + " GROUP BY Persone.id, Persone.cognome, Persone.nome, Persone.idattivita, Persone.idtessera, Persone.note "
                    + " HAVING (MAX(DettaglioAttivita.giorno) < { fn NOW() }) OR "
                    + " (Persone.idattivita IS NULL)", provaConnessione);

            com.Fill(data);
            return data;
        }

        public DataTable SelectTableAll()
        {
            DataTable data = new DataTable();

            Controller.Connector conn = Controller.Connector.Istance();
            SqlConnection provaConnessione = conn.Connessione;

            SqlDataAdapter com = new SqlDataAdapter(@"
SELECT       Persone.id As Id, Persone.nome, Persone.cognome, Persone.note, Alunni.id AS idAlunno, Dipendenti.id AS idDipendente, Docenti.id AS idDocente
FROM         Persone LEFT OUTER JOIN
                      Docenti ON Persone.id = Docenti.id LEFT OUTER JOIN
                      Dipendenti ON Persone.id = Dipendenti.id LEFT OUTER JOIN
                      Alunni ON Persone.id = Alunni.id", provaConnessione);
            com.Fill(data);
            data.Columns.Add("Tipo");

            foreach (DataRow dr in data.Rows)
            {
                if (!string.IsNullOrEmpty(Convert.ToString(dr[3]))) dr["Tipo"] = "Alunno";
                if (!string.IsNullOrEmpty(Convert.ToString(dr[4]))) dr["Tipo"] = "Dipendente";
                if (!string.IsNullOrEmpty(Convert.ToString(dr[5]))) dr["Tipo"] = "Docente";
            }
            return data;
        }

        public Persona SelectObjectPersonaById(Guid idPersona)
        {
            DataTable data = new DataTable();

            Controller.Connector con = Controller.Connector.Istance();
            SqlConnection conn = con.Connessione;

            string query = @"
            SELECT     Persone.id AS IdPersona, Persone.cognome AS CognomePersona, Persone.nome AS NomePersona, Persone.note AS NotePersona,Persone.idtessera AS IdTessera, Alunni.id AS IdAlunno, Dipendenti.id AS IdDipendente, Docenti.id AS IdDocente
            FROM       Persone LEFT OUTER JOIN
                       Alunni ON Persone.id = Alunni.id LEFT OUTER JOIN
                       Dipendenti ON Persone.id = Dipendenti.id LEFT OUTER JOIN
                       Docenti ON Persone.id = Docenti.id
                       WHERE Persone.id = '" + idPersona + "'";
            SqlDataAdapter adapter = new SqlDataAdapter(query, conn);
            adapter.Fill(data);

            // List<Persona> listaPersone = new List<Persona>();

            //  foreach (DataRow riga in data.Rows)
            //  {
            DataRow riga = data.Rows[0];
            Persona persona = null;
            if (riga[0].Equals(riga[5])) //alunno
            {
                persona = new Alunno();
            }
            if (riga[0].Equals(riga[6])) //dipendente
            {
                persona = new Dipendente();
            }
            if (riga[0].Equals(riga[7])) //docente
            {
                persona = new Docente();
            }
            persona.Id = (Guid)data.Rows[0][data.Columns["IdPersona"]];
            persona.Cognome = (string)data.Rows[0][data.Columns["CognomePersona"]];
            persona.Nome = (string)data.Rows[0][data.Columns["NomePersona"]];
            persona.Note = (string)data.Rows[0][data.Columns["NotePersona"]];
            if (data.Rows[0][data.Columns["IdTessera"]] != DBNull.Value)
                persona.Tessera = ctrlTessera.GetTesseraById((Guid)data.Rows[0][data.Columns["IdTessera"]]);
            else
                persona.Tessera = null;
            //}
            this.persona = persona;
            return persona;
        }

        public void DeleteTipologia(Persona persona)
        {
            if (persona is Alunno)
            {
                string query = " DELETE FROM Alunni WHERE id = @condizione";
                SqlCommand elimina = new SqlCommand(query, connector.Connessione);
                elimina.Parameters.AddWithValue("@condizione", persona.Id);
                elimina.ExecuteNonQuery();
            }
            else if (persona is Dipendente)
            {
                string query = " DELETE FROM Dipendenti WHERE id = @condizione";
                SqlCommand elimina = new SqlCommand(query, connector.Connessione);
                elimina.Parameters.AddWithValue("@condizione", persona.Id);
                elimina.ExecuteNonQuery();
            }
            else if (persona is Docente)
            {
                string query = " DELETE FROM Docenti WHERE id = @condizione";
                SqlCommand elimina = new SqlCommand(query, connector.Connessione);
                elimina.Parameters.AddWithValue("@condizione", persona.Id);
                elimina.ExecuteNonQuery();
            }
        }

        public bool DeletePersone(Guid idDaCancellare)
        {
            Controller.Connector con = Controller.Connector.Istance();
            persona = this.SelectObjectPersonaById(idDaCancellare);
            DeleteTipologia(persona);
            try
            {
                string queryPersone = " DELETE FROM Persone WHERE id = @condizione";
                SqlCommand eliminaPersone = new SqlCommand(queryPersone, con.Connessione);
                SqlParameter condizione = new SqlParameter();
                condizione.ParameterName = "@condizione";
                condizione.SqlDbType = SqlDbType.UniqueIdentifier;
                condizione.Value = idDaCancellare;
                eliminaPersone.Parameters.Add(condizione);
                eliminaPersone.ExecuteNonQuery();
                return true;
            }
            catch (SqlException ex)
            {
                if (persona is Alunno)
                {
                    InserisciAlunno(idDaCancellare);
                }
                else if (persona is Dipendente)
                {
                    InserisciDipendente(idDaCancellare);
                }
                else if (persona is Docente)
                {
                    InserisciDocente(idDaCancellare);
                }
                if (ex.Number == 547)
                {
                    throw new PersonaAssociataAdAttività();
                }
                return false;
            }
        }

        public DataTable SelectAll()
        {
            DataTable data = new DataTable();

            Controller.Connector conn = Controller.Connector.Istance();
            SqlConnection provaConnessione = conn.Connessione;

            SqlDataAdapter com = new SqlDataAdapter("select * from Persone", provaConnessione);
            com.Fill(data);

            return data;
        }

        public Tessera GetTesseraByCodice(string codice)
        {
            Controller.Connector conn = Controller.Connector.Istance();

            DataTable dataTable = new DataTable();
            Tessera daRitornare = new Tessera();
            string query = "SELECT * FROM Tessere WHERE codice = '" + codice + "'";

            try
            {
                SqlDataAdapter sda = new SqlDataAdapter(query, conn.Connessione);
                sda.Fill(dataTable);
            }
            catch (SqlException ex)
            {
                MessageBox.Show("Errore getTesseraByCodice" + ex.Message);
            }

            if (dataTable.Rows.Count > 0)
            {
                daRitornare.Id = (Guid)dataTable.Rows[0]["id"];
                daRitornare.Codice = (string)dataTable.Rows[0]["codice"];
                daRitornare.Abilitata = (bool)dataTable.Rows[0]["abilitata"];
                return daRitornare;
            }
            return null;
        }

        public DataTable SelectAllAlunni()
        {
            DataTable data = new DataTable();

            Controller.Connector conn = Controller.Connector.Istance();
            SqlConnection provaConnessione = conn.Connessione;

            SqlDataAdapter com = new SqlDataAdapter("SELECT Persone.id AS Id, Persone.nome AS Nome, Persone.cognome AS Cognome "
                        + " FROM Persone LEFT JOIN "
                        + " Alunni ON Persone.id = Alunni.id", provaConnessione);
            com.Fill(data);

            return data;
        }

        private bool ControllaUnivocitaTessera()
        {
            Controller.Connector conn = Controller.Connector.Istance();

            SqlConnection provaConnessione = conn.Connessione;

            SqlCommand selectCodiceTessera = new SqlCommand(
                "Select * from Tessere where codice='" + persona.Tessera.Codice + "'"
                , provaConnessione);

            return true;
        }

        public int setPersonaToAttivita(Attivita attivita)
        {
            Controller.Connector conn = Controller.Connector.Istance();
            SqlConnection provaConnessione = conn.Connessione;

            string sql;
            sql = "UPDATE Persone SET idattivita='" + attivita.Id + "'"
                + " WHERE id='" + persona.Id + "'";
            SqlCommand cmd = new SqlCommand(sql, provaConnessione);
            return cmd.ExecuteNonQuery();
        }

        public int setPersonaToAttivitaNULL(Attivita attivita)
        {
            Controller.Connector conn = Controller.Connector.Istance();
            SqlConnection provaConnessione = conn.Connessione;

            string sql;
            sql = "UPDATE Persone SET idattivita=NULL"
                + " WHERE id='" + persona.Id + "'";
            SqlCommand cmd = new SqlCommand(sql, provaConnessione);
            return cmd.ExecuteNonQuery();
        }

        private void InserisciDipendente(Guid idPersona)
        {
            Controller.Connector conn = Controller.Connector.Istance();

            SqlConnection provaConnessione = conn.Connessione;

            SqlCommand insertDip = new SqlCommand(@"
                Insert into Dipendenti
                (id)
                values(@id)
            ", provaConnessione);

            SqlParameter id = new SqlParameter();

            id.ParameterName = "@id";
            id.DbType = DbType.Guid;
            id.Value = idPersona;
            insertDip.Parameters.Add(id);

            insertDip.ExecuteNonQuery();
        }

        private void InserisciAlunno(Guid idPersona)
        {
            Controller.Connector conn = Controller.Connector.Istance();

            SqlConnection provaConnessione = conn.Connessione;

            SqlCommand insertAlunn = new SqlCommand(@"
                Insert into Alunni
                (id)
                values(@id)
            ", provaConnessione);

            SqlParameter id = new SqlParameter();

            id.ParameterName = "@id";
            id.DbType = DbType.Guid;
            id.Value = idPersona;
            insertAlunn.Parameters.Add(id);

            insertAlunn.ExecuteNonQuery();
        }

        private void InserisciDocente(Guid idPersona)
        {
            Controller.Connector conn = Controller.Connector.Istance();

            SqlConnection provaConnessione = conn.Connessione;

            SqlCommand insertDoc = new SqlCommand(@"
                Insert into Docenti
                (id)
                values(@id)
            ", provaConnessione);

            SqlParameter id = new SqlParameter();

            id.ParameterName = "@id";
            id.DbType = DbType.Guid;
            id.Value = idPersona;
            insertDoc.Parameters.Add(id);

            insertDoc.ExecuteNonQuery();
        }

        public void UpdatePersona(Persona persona, bool cambioTipo) // da finire
        {
            SqlCommand update = new SqlCommand(@"
                UPDATE Persone set nome = @nome, cognome = @cognome, idtessera = @idtessera, note = @note
                WHERE id = @id
            ", connector.Connessione);

            SqlParameter id = new SqlParameter();

            id.ParameterName = "@id";
            id.DbType = DbType.Guid;
            id.Value = persona.Id;
            update.Parameters.Add(id);

            SqlParameter nome = new SqlParameter();

            nome.ParameterName = "@nome";
            nome.DbType = DbType.String;
            nome.Value = persona.Nome;
            update.Parameters.Add(nome);

            SqlParameter cognome = new SqlParameter();

            cognome.ParameterName = "@cognome";
            cognome.DbType = DbType.String;
            cognome.Value = persona.Cognome;
            update.Parameters.Add(cognome);

            SqlParameter idTessera = new SqlParameter();

            if (persona.Tessera != null)
            {
                if (ctrlTessera.ControllaSeAssociata(persona.Tessera) == true)
                    AnnullaAssociazioneTessera(persona.Tessera.Id);
            }

            idTessera.ParameterName = "@idtessera";
            if (persona.Tessera != null)
            {
                idTessera.DbType = DbType.Guid;
                idTessera.Value = persona.Tessera.Id;
            }
            else
                idTessera.Value = DBNull.Value;
            update.Parameters.Add(idTessera);

            SqlParameter note = new SqlParameter();

            note.ParameterName = "@note";
            note.DbType = DbType.String;
            note.Value = persona.Note;
            update.Parameters.Add(note);

            update.ExecuteNonQuery();
            if (cambioTipo)
            {
                Persona vecchiaPersona = SelectObjectPersonaById(persona.Id);
                DeleteTipologia(vecchiaPersona);
                if (persona is Dipendente)
                {
                    InserisciDipendente(persona.Id);
                    MessageBox.Show("Dipendente modificato correttamente");
                }
                else if (persona is Alunno)
                {
                    InserisciAlunno(persona.Id);
                    MessageBox.Show("Alunno modificato correttamente");
                }
                else if (persona is Docente)
                {
                    InserisciDocente(persona.Id);
                    MessageBox.Show("Docente modificato correttamente");
                }
            }
        }

        public int InsertPersonaTessera(Persona persona)
        {
            Controller.Connector conn = Controller.Connector.Istance();
            int numeroRigheModificate = 0;
            SqlConnection provaConnessione = conn.Connessione;

            SqlCommand insertPersona = new SqlCommand(@"
                Insert into Persone
                (id,nome,cognome,idtessera,note)
                values(@id,@nome,@cognome,@idtessera,@note)
            ", provaConnessione);

            SqlParameter id = new SqlParameter();

            id.ParameterName = "@id";
            id.DbType = DbType.Guid;
            id.Value = persona.Id;
            insertPersona.Parameters.Add(id);

            SqlParameter nome = new SqlParameter();

            nome.ParameterName = "@nome";
            nome.DbType = DbType.String;
            nome.Value = persona.Nome;
            insertPersona.Parameters.Add(nome);

            SqlParameter cognome = new SqlParameter();

            cognome.ParameterName = "@cognome";
            cognome.DbType = DbType.String;
            cognome.Value = persona.Cognome;
            insertPersona.Parameters.Add(cognome);
            // se esiste già una persona con quella tessera associata allora cancella l'associazione
            if (persona.Tessera != null)
            {
                if (ctrlTessera.ControllaSeAssociata(persona.Tessera) == true)
                    AnnullaAssociazioneTessera(persona.Tessera.Id);
            }

            SqlParameter idTessera = new SqlParameter();

            idTessera.ParameterName = "@idtessera";
            if (persona.Tessera != null)
            {
                idTessera.DbType = DbType.Guid;
                idTessera.Value = persona.Tessera.Id;
            }
            else
                idTessera.Value = DBNull.Value;
            insertPersona.Parameters.Add(idTessera);

            SqlParameter note = new SqlParameter();

            note.ParameterName = "@note";
            note.DbType = DbType.String;
            note.Value = persona.Note;
            insertPersona.Parameters.Add(note);
            try
            {
                numeroRigheModificate = insertPersona.ExecuteNonQuery();
            }
            catch (SqlException ex)
            {
                MessageBox.Show(ex.Message);
            }
            if (persona is Dipendente)
            {
                InserisciDipendente(persona.Id);
                if (numeroRigheModificate > 0)
                    MessageBox.Show("Dipendente inserito correttamente");
            }
            else if (persona is Alunno)
            {
                InserisciAlunno(persona.Id);
                if (numeroRigheModificate > 0)
                    MessageBox.Show("Alunno inserito correttamente");
            }
            else if (persona is Docente)
            {
                InserisciDocente(persona.Id);
                if (numeroRigheModificate > 0)
                    MessageBox.Show("Docente inserito correttamente");
            }
            return numeroRigheModificate;
        }

        public DataTable VerificaPersoneAttivita(Guid id)
        {
            DataTable dt = new DataTable();

            Controller.Connector conn = Controller.Connector.Istance();
            SqlConnection provaConnessione = conn.Connessione;

            SqlDataAdapter com = new SqlDataAdapter("select cognome, nome from persone where id='" + id + "' ", provaConnessione);

            com.Fill(dt);

            return dt;
        }

        public void AnnullaAssociazioneTessera(Persona personaPrecedente)
        {
            Controller.Connector conn = Controller.Connector.Istance();

            string query = "Update Persone set idtessera = NULL Where id = '" + personaPrecedente.Id + "'";

            SqlCommand update = new SqlCommand(query, conn.Connessione);
            update.ExecuteNonQuery();
        }

        /// <summary>
        /// Annulla l'associazione che c'è tra persona e Tessera, passandogli l'id della tessera Stessa
        /// </summary>
        /// <param name="idTessera">Id della tessera da disassociare </param>
        public void AnnullaAssociazioneTessera(Guid idTessera)
        {
            Controller.Connector conn = Controller.Connector.Istance();

            string query = "Update Persone set idtessera = NULL Where idtessera = '" + idTessera + "'";

            SqlCommand update = new SqlCommand(query, conn.Connessione);
            update.ExecuteNonQuery();
        }

        public int UpdateTessera(Tessera tesseraDaAssociare, Guid idPersona)
        {
            string query = "UPDATE Persone Set idtessera = @idtessera WHERE id = @id";
            SqlCommand update = new SqlCommand(query, connector.Connessione);

            if (ctrlTessera.ControllaSeAssociata(persona.Tessera) == true)
                AnnullaAssociazioneTessera(persona.Tessera.Id);

            SqlParameter idtessera = new SqlParameter();
            idtessera.DbType = DbType.Guid;
            idtessera.ParameterName = "@idtessera";
            idtessera.Value = tesseraDaAssociare.Id;
            update.Parameters.Add(idtessera);

            SqlParameter id = new SqlParameter();
            id.DbType = DbType.Guid;
            id.ParameterName = "@id";
            id.Value = idPersona;
            update.Parameters.Add(id);

            return update.ExecuteNonQuery();
        }
    }
}